﻿using AutoMapper;
using HamcoWcs.Contract.ContractCommon;
using HamcoWcs.Contract.ContractForeEnd;
using HamcoWcs.DAL;
using HamcoWcs.Entitys.BaseConfigs;
using HamcoWcs.Models.Common;
using HamcoWcs.Models.Devices;
using HamcoWcs.Models.Exceptions;
using HamcoWcs.Models.ForeEndModels.DeviceMsgQueues;
using HamcoWcs.Models.LcdInfos;
using HamcoWcs.Models.Monitors;
using HamcoWcs.Service.Common;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using static System.Net.WebRequestMethods;

namespace HamcoWcs.Main.Controllers.Wcs
{
    /// <summary>获取设备信息接口</summary>
    public class DeviceDataController : BasicController
    {

        private static string millageFolder = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "logs", "milage_logs");

        /// <summary>获取设备信息</summary>
        [HttpPost]
        public IActionResult GetDeviceData(string deviceName)
        {
            try
            {
                var result = _dataService.GetDeviceData(deviceName);
                return Json(result);
            }
            catch (System.Exception ex)
            {
                AddSystemLog(ex.Message);
                return QueryFailureResult();
            }
        }

        /// <summary>获取设备当前异常信息</summary>
        [HttpPost]
        public IActionResult GetDeviceErrorData()
        {
            try
            {
                var errs = _wcsDbContext.DeviceErrorQueues.ToList();

                return Json(new ForeEndResult(errs));
            }
            catch (WarningException ex)
            {
                return Warning(ex);
            }
            catch (System.Exception ex)
            {
                AddSystemLog(ex.Message);
                return QueryFailureResult();
            }
        }

        /// <summary>清除设备当前异常信息</summary>
        [HttpPost]
        public IActionResult ClearDeviceErrorData(BaseModel model, [FromHeader] string userName = "UNK")
        {
            try
            {
                var err = _wcsDbContext.DeviceErrorQueues.FirstOrDefault(x => x.Id == model.Id)
                    ?? throw new WarningException("未找到对应异常信息");

                _wcsDbContext.Remove(err);
                _wcsDbContext.SaveChanges();
                AddOperationLog(userName, $"清除设备异常日志{err.MachineName},{err.ErrorDetail}");
                return Json(ForeEndResult.Ok);
            }
            catch (WarningException ex)
            {
                return Warning(ex);
            }
            catch (System.Exception ex)
            {
                AddSystemLog(ex.Message);
                return QueryFailureResult();
            }
        }


        /// <summary>获取生产计划信息</summary>
        [HttpPost]
        public IActionResult GetStockerPlan()
        {
            try
            {
                return Json(new ForeEndResult(StockerPlanInfo.StockerPlanDic));
            }
            catch (System.Exception ex)
            {
                AddSystemLog(ex.Message);
                return QueryFailureResult();
            }
        }


        /// <summary>获取设备空前/繁忙统计</summary>
        [HttpPost]
        public IActionResult GetDeviceEvent(DeviceEventModel model)
        {
            try
            {
                var now = DateTime.Now;
                var events = _wcsDbContext.Set<DeviceEvent>()
                    .AsNoTracking()
                    .Where(x => x.MachineName == model.MachineName)
                    .Where(x => x.SetTime >= now.AddDays(0 - model.Days))
                    .Select(x => new UIDeviceEventInfo(x.Description, x.SetTime, x.Description == "HIGH" ? "#E6A23C" : "#67C23A"))
                    .ToList();

                return Json(new ForeEndResult(events));
            }
            catch (System.Exception ex)
            {
                AddSystemLog(ex.Message);
                return QueryFailureResult();
            }
        }

        /// <summary>获取当前异常点位</summary>
        [HttpPost]
        public IActionResult GetCurrentErrorBit()
        {
            try
            {
                return Json(new ForeEndResult(_monitorBaseService.GetMonitorData().ErrorBits));
            }
            catch (System.Exception ex)
            {
                AddSystemLog(ex.Message);
                return QueryFailureResult();
            }
        }

        /// <summary>
        /// 清理当前里程数
        /// </summary>
        /// <param name="motorMileages"></param>
        /// <returns></returns>
        [HttpPost]
        public IActionResult ClearMileage(List<MotorMileage> motorMileages)
        {
            try
            {
                foreach(var mile in motorMileages)
                {
                    _mileageConfigService.SetMileageConfig($"{mile.Name}-{mile.DeviceType}",mile.Mileage);
                }
                _mileageConfigService.SaveMileageConfig();
                return Json(ForeEndResult.Ok);
            }
            catch (WarningException ex)
            {
                return Warning(ex);
            }
            catch (System.Exception ex)
            {
                AddSystemLog(ex.Message);
                return QueryFailureResult();
            }
        }

        /// <summary>获取里程</summary>
        [HttpPost]
        public IActionResult GetMileage()
        {
            try
            {
                var plc = _asrs.ConveyorDic["Pcon01"];
                var miles = _asrs.MotorMileages;

                var content = plc.DbInfo.First(x => x.DbNum == 103).Buffer;

                var srm1db = _asrs.SrmDic["SrmPlc01"].DbInfo;
                var srm2db = _asrs.SrmDic["SrmPlc02"].DbInfo;
                var srm1c1content = srm1db.First(x => x.DbName == "c1_mile").Buffer;
                var srm1c2content = srm1db.First(x => x.DbName == "c2_mile").Buffer;
                var srm2c1content = srm2db.First(x => x.DbName == "c1_mile").Buffer;
                var srm2c2content = srm2db.First(x => x.DbName == "c2_mile").Buffer;

                foreach (var m in miles)
                {
                    if (m.DeviceType == "pcon")
                    {
                        m.Update(content);
                        // 测试
                        // 更新是取消
                        //m.Mileage = 1;
                    }
                    else
                    {
                        if (m.DeviceType == "SrmPlc01C1")
                        {
                            m.UpdateSrm(srm1c1content);
                        }
                        if (m.DeviceType == "SrmPlc01C2")
                        {
                            m.UpdateSrm(srm1c2content);
                        }
                        if (m.DeviceType == "SrmPlc02C1")
                        {
                            m.UpdateSrm(srm2c1content);
                        }
                        if (m.DeviceType == "SrmPlc02C2")
                        {
                            m.UpdateSrm(srm2c2content);
                        }
                    }
                    m.Mileage2 = m.Mileage - _mileageConfigService.GetMileageConfig($"{m.Name}-{m.DeviceType}");
                }

                //var list = miles.GroupBy(x=>x.MachineName).Select(x=>new { GroupName=x.Key,Miles = x}).ToList();


                return Json(new ForeEndResult(miles.OrderBy(X => X.MachineName).ThenBy(X => X.PortName)));
            }
            catch (System.Exception ex)
            {
                AddSystemLog(ex.Message);
                return QueryFailureResult();
            }
        }


        /// <summary>获取历史里程列表</summary>
        [HttpPost]
        public IActionResult GetHistoryMileageList()
        {
            try
            {
                var a = Directory.GetFiles(millageFolder).Select(Path.GetFileNameWithoutExtension).ToList();
                return Json(new ForeEndResult(a));
            }
            catch (System.Exception ex)
            {
                AddSystemLog(ex.Message);
                return QueryFailureResult();
            }
        }

        

        /// <summary>获取历史里程列表</summary>
        [HttpPost]
        public IActionResult GetHistoryMileage(HistoryMileageQueryModel model)
        {
            try
            {
                var fileName = Path.Combine(millageFolder, model.Q);

                var str = System.IO.File.ReadAllText(fileName);

                var o = JsonConvert.DeserializeObject<List<MotorMileage>>(str);
                return Json(new ForeEndResult(o));
            }
            catch (System.Exception ex)
            {
                AddSystemLog(ex.Message);
                return QueryFailureResult();
            }
        }

        /// <summary>重置里程</summary>
        [HttpPost]
        public IActionResult ResetMileage(ResetMileageModel model, [FromHeader] string userName = "UNK")
        {
            try
            {
                var m = _asrs.MotorMileages.FirstOrDefault(x => x.Name == model.MotorName)
                    ?? throw new WarningException("未找到对应马达");

                if (m.DeviceType == "pcon")
                {
                    var rm = _asrs.MotorReset.FirstOrDefault(x => x.Name == m.Name);
                    if (rm != null) throw new WarningException("重置中，请勿重复操作");
                    _asrs.MotorReset.Add(m);
                }
                else
                {
                    // srm 未完成
                }

                return Json(ForeEndResult.Ok);
            }
            catch (WarningException ex)
            {
                return Warning(ex);
            }
            catch (System.Exception ex)
            {
                AddSystemLog(ex.Message);
                return QueryFailureResult();
            }
        }

        /// <summary>获取电箱参数</summary>
        [HttpPost]
        public IActionResult GetCabinetData()
        {
            try
            {
                var a = _monitorBaseService.GetMonitorData().CabinetParas;
                return Json(new ForeEndResult(a));
            }
            catch (System.Exception ex)
            {
                AddSystemLog(ex.Message);
                return QueryFailureResult();
            }
        }

        /// <summary>设置BCRBypass状态</summary>
        [HttpPost]
        public IActionResult SetBcrBypassState(SetBcrBypassModel model, [FromHeader] string userName = "UNK")
        {
            try
            {
                var a = _monitorBaseService.GetMonitorData().BCRMonitors;

                var bcr = a.FirstOrDefault(x => x.BcrName == model.BcrName)
                    ?? throw new WarningException("未找到对应BCR");

                bcr.Cmd = model.BypassState ? 2 : 1;

                var tt = model.BypassState ? "禁用" : "启用";
                AddOperationLog(userName, $"设置{model.BcrName}({bcr.Remark})为{tt}");
                return Json(ForeEndResult.Ok);
            }
            catch (WarningException ex)
            {
                return Warning(ex);
            }
            catch (System.Exception ex)
            {
                AddSystemLog(ex.Message);
                return QueryFailureResult();
            }
        }

        /// <summary>重新获取RGV Teaching值</summary>
        [HttpPost]
        public IActionResult ResetRgvTeachingValue([FromHeader] string userName = "UNK")
        {
            try
            {
                foreach (var pcon in _asrs.Pcons)
                {
                    pcon.RgvPosition = 0;
                }

                AddOperationLog(userName, "重新获取RGV Teaching值");
                return Json(ForeEndResult.Ok);
            }
            catch (WarningException ex)
            {
                return Warning(ex);
            }
            catch (System.Exception ex)
            {
                AddSystemLog(ex.Message);
                return QueryFailureResult();
            }
        }

        /// <summary>重新获取RGV Teaching值</summary>
        [HttpPost]
        public IActionResult SetTransportThresholdTime(SetTransportThresholdTimeModel model, [FromHeader] string userName = "UNK")
        {
            try
            {
                if (string.IsNullOrEmpty(model.Remark))
                    throw new WarningException("清输入备注");

                if (model.Time * 60 >= short.MaxValue || model.Time <= 0)
                    throw new WarningException("设置的值超限");

                var a = _monitorBaseService.GetMonitorData().ThresholdMonitors;

                var t = a.FirstOrDefault(x => x.FieldName == model.FieldName)
                    ?? throw new WarningException($"未找到对应配置项:{model.FieldName}");


                t.Cmd = (short)(model.Time * t.Gain);


                AddOperationLog(userName, $"设置{model.FieldName},值：{model.Time}({model.Remark})");
                return Json(ForeEndResult.Ok);
            }
            catch (WarningException ex)
            {
                return Warning(ex);
            }
            catch (System.Exception ex)
            {
                AddSystemLog(ex.Message);
                return QueryFailureResult();
            }
        }

        /// <summary>获取堆垛机货位的定位信息</summary>
        [HttpPost]
        public IActionResult GetShelfTeach4Srm(GetShelfTeachInfoModel model)
        {
            try
            {
                if (string.IsNullOrEmpty(model.ShelfName)) throw new WarningException("请输入货架名");
                if (!model.ShelfName.IsShelf()) throw new WarningException("请输入正确货架名");
                var a = int.TryParse(model.ShelfName[..2], out int row);
                if (!a || row < 1 || row > 4) throw new WarningException("请输入正确货架名");

                if (GlobalValue.TeachShelfNames.Any(x=>x == model.ShelfName))
                    throw new WarningException("查询队列中已经有此货架");

                GlobalValue.TeachShelfNames.Enqueue(model.ShelfName);

                return Json(ForeEndResult.Ok);
            }
            catch (WarningException ex)
            {
                return Warning(ex);
            }
            catch (System.Exception ex)
            {
                AddSystemLog(ex.Message);
                return QueryFailureResult();
            }
        }

        #region Constructor

        private readonly IForeEndGetDataService _dataService;
        private readonly IMonitorBaseService _monitorBaseService;
        private readonly IMileageConfigService _mileageConfigService;

        /// <summary>
        /// 
        /// </summary>
        public override string ControllerName => "DeviceDataController";

        private readonly AutomaticStorageInfo _asrs;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="dataService"></param>
        /// <param name="wcsDbContext"></param>
        /// <param name="mapper"></param>
        /// <param name="logger"></param>
        public DeviceDataController(AutomaticStorageInfo asrs, IForeEndGetDataService dataService, WcsDbContext wcsDbContext, IMapper mapper, ILoggerService logger,
            IMonitorBaseService monitorBaseService, IMileageConfigService mileageConfigService)
            : base(logger, mapper, wcsDbContext)
        {
            _monitorBaseService = monitorBaseService;
            _dataService = dataService;
            _asrs = asrs;
            _mileageConfigService = mileageConfigService;
        }

        #endregion Constructor
    }



}
